#    pythonequations is a collection of equations expressed as Python classes
#    Copyright (C) 2008 James R. Phillips
#    2548 Vera Cruz Drive
#    Birmingham, AL 35235 USA
#    email: zunzun@zunzun.com
#
#    License: BSD-style (see LICENSE.txt in main source directory)
#    Version info: $Id: Power.py 274 2010-09-29 13:16:14Z zunzun.com $

import pythonequations, pythonequations.EquationBaseClasses, pythonequations.ExtraCodeForEquationBaseClasses
import numpy
numpy.seterr(all = 'raise') # numpy raises warnings, convert to exceptions to trap them


class PowerRoot2D(pythonequations.EquationBaseClasses.Equation2D):
    RequiresAutoGeneratedGrowthAndDecayForms = True
    RequiresAutoGeneratedOffsetForm = True
    RequiresAutoGeneratedReciprocalForm = True
    RequiresAutoGeneratedInverseForms = True
    _name = "Root"
    _HTML = "y = a<SUP>(1.0/x)</SUP>"
    coefficientDesignatorTuple = ("a")
    CannotAcceptDataWithZeroX = True
    function_cpp_code = 'temp = pow(coeff[0], _id[_cwo[0]+i]);'


    def CreateCacheGenerationList(self):
        self.CacheGenerationList = []
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_PowX(NameOrValueFlag=1, args=[-1.0]), [-1.0]])

    def SpecificCodeCPP(self):
        s = "\ttemp = pow(a, (1.0/x_in));\n"
        return s



class Geometric_Modified2D(pythonequations.EquationBaseClasses.Equation2D):
    RequiresAutoGeneratedGrowthAndDecayForms = True
    RequiresAutoGeneratedOffsetForm = True
    RequiresAutoGeneratedReciprocalForm = True
    RequiresAutoGeneratedInverseForms = True
    _name = "Geometric Modified"
    _HTML = "y = a * x<SUP>(b/x)</SUP>"
    coefficientDesignatorTuple = ("a", "b")
    CannotAcceptDataWithZeroX = True
    function_cpp_code = 'temp = coeff[0] * pow(_id[_cwo[0]+i], coeff[1] * _id[_cwo[1]+i]);'


    def CreateCacheGenerationList(self):
        self.CacheGenerationList = []
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_X(NameOrValueFlag=1), []])
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_PowX(NameOrValueFlag=1, args=[-1.0]), [-1.0]])

    def SpecificCodeCPP(self):
        s = "\ttemp = a * pow(x_in, (b/x_in));\n"
        return s



class StandardGeometric2D(pythonequations.EquationBaseClasses.Equation2D):
    RequiresAutoGeneratedGrowthAndDecayForms = True
    RequiresAutoGeneratedOffsetForm = True
    RequiresAutoGeneratedReciprocalForm = True
    RequiresAutoGeneratedInverseForms = True
    _name = "Standard Geometric"
    _HTML = "y = a * x<SUP>bx</SUP>"
    coefficientDesignatorTuple = ("a", "b")
    function_cpp_code = 'temp = coeff[0] * pow(_id[_cwo[0]+i], coeff[1] * _id[_cwo[0]+i]);'


    def CreateCacheGenerationList(self):
        self.CacheGenerationList = []
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_X(NameOrValueFlag=1), []])

    def SpecificCodeCPP(self):
        s = "\ttemp = a * pow(x_in, (b*x_in));\n"
        return s



class XShiftedPower2D(pythonequations.EquationBaseClasses.Equation2D):
    RequiresAutoGeneratedGrowthAndDecayForms = True
    RequiresAutoGeneratedOffsetForm = True
    RequiresAutoGeneratedReciprocalForm = True
    RequiresAutoGeneratedInverseForms = True
    _name = "X Shifted Power"
    _HTML = "y = a * (x-b)<SUP>c</SUP>"
    coefficientDesignatorTuple = ("a", "b", "c")
    function_cpp_code = 'temp = coeff[0] * pow(_id[_cwo[0]+i] - coeff[1], coeff[2]);'


    def CreateCacheGenerationList(self):
        self.CacheGenerationList = []
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_X(NameOrValueFlag=1), []])
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_Ones(NameOrValueFlag=1), []])
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_Ones(NameOrValueFlag=1), []])

    def SpecificCodeCPP(self):
        s = "\ttemp = a * pow((x_in-b), c);\n"
        return s



class SimplePower2D(pythonequations.EquationBaseClasses.Equation2D):
    RequiresAutoGeneratedGrowthAndDecayForms = True
    RequiresAutoGeneratedOffsetForm = True
    RequiresAutoGeneratedReciprocalForm = False
    RequiresAutoGeneratedInverseForms = False
    _name = "Simple Power"
    _HTML = "y = x<SUP>a</SUP>"
    coefficientDesignatorTuple = ("a")
    function_cpp_code = 'temp = pow(_id[_cwo[0]+i], coeff[0]);'


    def CreateCacheGenerationList(self):
        self.CacheGenerationList = []
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_X(NameOrValueFlag=1), []])

    def SpecificCodeCPP(self):
        s = "\ttemp = pow(x_in, a);\n"
        return s



class StandardPower2D(pythonequations.EquationBaseClasses.Equation2D):
    RequiresAutoGeneratedGrowthAndDecayForms = True
    RequiresAutoGeneratedOffsetForm = True
    RequiresAutoGeneratedReciprocalForm = True
    RequiresAutoGeneratedInverseForms = True
    _name = "Standard Power"
    _HTML = "y = a * x<SUP>b</SUP>"
    coefficientDesignatorTuple = ("a", "b")
    function_cpp_code = 'temp = coeff[0] * pow(_id[_cwo[0]+i], coeff[1]);'


    def CreateCacheGenerationList(self):
        self.CacheGenerationList = []
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_X(NameOrValueFlag=1), []])
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_Ones(NameOrValueFlag=1), []])

    def SpecificCodeCPP(self):
        s = "\ttemp = a * pow(x_in, b);\n"
        return s



class PowerA_Modified2D(pythonequations.EquationBaseClasses.Equation2D):
    RequiresAutoGeneratedGrowthAndDecayForms = True
    RequiresAutoGeneratedOffsetForm = True
    RequiresAutoGeneratedReciprocalForm = True
    RequiresAutoGeneratedInverseForms = True
    _name = "Power A Modified"
    _HTML = "y = a * b<SUP>x</SUP>"
    coefficientDesignatorTuple = ("a", "b")
    function_cpp_code = 'temp = coeff[0] * pow(coeff[1], _id[_cwo[0]+i]);'


    def CreateCacheGenerationList(self):
        self.CacheGenerationList = []
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_X(NameOrValueFlag=1), []])
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_Ones(NameOrValueFlag=1), []])

    def SpecificCodeCPP(self):
        s = "\ttemp = a * pow(b, x_in);\n"
        return s



class PowerA_Modified_Transform2D(pythonequations.EquationBaseClasses.Equation2D):
    RequiresAutoGeneratedGrowthAndDecayForms = True
    RequiresAutoGeneratedOffsetForm = True
    RequiresAutoGeneratedReciprocalForm = True
    RequiresAutoGeneratedInverseForms = True
    _name = "Power A Modified Transform"
    _HTML = "y = a * b<SUP>cx + d</SUP>"
    coefficientDesignatorTuple = ("a", "b", 'c', 'd')
    function_cpp_code = 'temp = coeff[0] * pow(coeff[1], coeff[2] * _id[_cwo[0]+i] + coeff[3]);'


    def CreateCacheGenerationList(self):
        self.CacheGenerationList = []
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_X(NameOrValueFlag=1), []])

    def SpecificCodeCPP(self):
        s = "\ttemp = a * pow(b, c * x_in + d);\n"
        return s



class PowerB_Modified2D(pythonequations.EquationBaseClasses.Equation2D):
    RequiresAutoGeneratedGrowthAndDecayForms = True
    RequiresAutoGeneratedOffsetForm = True
    RequiresAutoGeneratedReciprocalForm = True
    RequiresAutoGeneratedInverseForms = True
    _name = "Power B Modified"
    _HTML = "y = a<SUP>ln(x)</SUP>"
    coefficientDesignatorTuple = ("a")
    CannotAcceptDataWithZeroX = True
    CannotAcceptDataWithNegativeX = True
    function_cpp_code = 'temp = pow(coeff[0], _id[_cwo[0]+i]);'


    def CreateCacheGenerationList(self):
        self.CacheGenerationList = []
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_LogX(NameOrValueFlag=1), []])
    
    def SpecificCodeCPP(self):
        s = "\ttemp = pow(a, log(x_in));\n"
        return s



class PowerB_Modified_Transform2D(pythonequations.EquationBaseClasses.Equation2D):
    RequiresAutoGeneratedGrowthAndDecayForms = True
    RequiresAutoGeneratedOffsetForm = True
    RequiresAutoGeneratedReciprocalForm = True
    RequiresAutoGeneratedInverseForms = True
    _name = "Power B Modified Transform"
    _HTML = "y = a<SUP>ln(bx + c)</SUP>"
    coefficientDesignatorTuple = ("a", 'b', 'c')
    function_cpp_code = 'temp = pow(coeff[0], log(coeff[1] * _id[_cwo[0]+i] + coeff[2]));'


    def CreateCacheGenerationList(self):
        self.CacheGenerationList = []
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_X(NameOrValueFlag=1), []])
    
    def SpecificCodeCPP(self):
        s = "\ttemp = pow(a, log(b * x_in + c));\n"
        return s



class PowerC_Modified2D(pythonequations.EquationBaseClasses.Equation2D):
    RequiresAutoGeneratedGrowthAndDecayForms = True
    RequiresAutoGeneratedOffsetForm = True
    RequiresAutoGeneratedReciprocalForm = True
    RequiresAutoGeneratedInverseForms = True
    _name = "Power C Modified"
    _HTML = "y = (a + x)<SUP>b</SUP>"
    coefficientDesignatorTuple = ("a", "b")
    function_cpp_code = 'temp = pow(coeff[0] + _id[_cwo[0]+i], coeff[1]);'


    def CreateCacheGenerationList(self):
        self.CacheGenerationList = []
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_X(NameOrValueFlag=1), []])
    
    def SpecificCodeCPP(self):
        s = "\ttemp = pow(a + x_in, b);\n"
        return s



class PowerC_Modified_Transform2D(pythonequations.EquationBaseClasses.Equation2D):
    RequiresAutoGeneratedGrowthAndDecayForms = True
    RequiresAutoGeneratedOffsetForm = True
    RequiresAutoGeneratedReciprocalForm = True
    RequiresAutoGeneratedInverseForms = True
    _name = "Power C Modified Transform"
    _HTML = "y = (a + bx)<SUP>c</SUP>"
    coefficientDesignatorTuple = ("a", "b", 'c')
    function_cpp_code = 'temp = pow(coeff[0] + coeff[1] * _id[_cwo[0]+i], coeff[2]);'


    def CreateCacheGenerationList(self):
        self.CacheGenerationList = []
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_X(NameOrValueFlag=1), []])
    
    def SpecificCodeCPP(self):
        s = "\ttemp = pow(a + b * x_in, c);\n"
        return s



class PowerLawExponentialCutoff2D(pythonequations.EquationBaseClasses.Equation2D):
    RequiresAutoGeneratedGrowthAndDecayForms = True
    RequiresAutoGeneratedOffsetForm = True
    RequiresAutoGeneratedReciprocalForm = True
    RequiresAutoGeneratedInverseForms = True
    _name = "Power Law With Exponential Cutoff"
    _HTML = "p(k) = C * k<SUP>(-T)</SUP> * exp(-k/K)"
    coefficientDesignatorTuple = ("C", "T", "K")
    function_cpp_code = 'temp = coeff[0] * pow(_id[_cwo[2]+i], -1.0 * coeff[1]) * exp(-1.0 * _id[_cwo[2]+i] / coeff[2]);'


    def CreateCacheGenerationList(self):
        self.CacheGenerationList = []
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_Ones(NameOrValueFlag=1), []])
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_Ones(NameOrValueFlag=1), []])
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_X(NameOrValueFlag=1), []])

    def SpecificCodeCPP(self):
        s = "\ttemp = C * pow(x_in, -1.0 * T) * exp(-1.0 * x_in / K);\n"
        return s
